//公共方法属性
let __utils = {
	winWidth: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
	winHeight: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}

/**
 * 防抖函数
 * @param {Function} fn 
 * @param {Number} delay 
 */
__utils.debounce = function(fn, delay) {
	var timer = null;
	return function() {
		var arg = arguments
		clearTimeout(timer)
		timer = setTimeout(function() {
			fn.apply(this, arg)
		}, delay)
	}
}

/**
 * 节流函数
 * @param {Function} fn 
 * @param {Number} delay 
 */
__utils.throttle = function(fn, delay) {
	let flag = true
	return function() {
		if(!flag) return
		flag = false
		var arg = arguments
		setTimeout(function() {
			fn.apply(this, arg)
			flag = true
		}, delay)
	}
}

/**
 * 深拷贝对象
 * @param {Object} obj
 */
__utils.DeepClone = function(obj) {
	if(obj === null || typeof obj !== 'object') return obj;
	var cpObj = obj instanceof Array ? [] : {};
	for(var key in obj) cpObj[key] = this.DeepClone(obj[key]);
	return cpObj;
}

/**
 * 深层合并
 * @param {Object} obj1
 * @param {Object} obj2
 */
__utils.deepMerge = function(obj1, obj2) {
	const result = {
		...obj2
	};
	for(const key in obj1) {
		var value1 = obj1[key]
		var value2 = result[key]
		if(Object.prototype.hasOwnProperty.call(result, key)) {
			if(Object.prototype.toString.call(value1) === '[object Object]' && Object.prototype.toString.call(
					value2) === '[object Object]') {
				result[key] = this.deepMerge(value1, value2)
			}
		} else {
			result[key] = value1
		}
	}
	return result
}

//重写Object.assign原型方法，为支持ie
if(typeof Object.assign != 'function') {
	Object.assign = function(target) {
		'use strict';
		if(target == null) {
			throw new TypeError('Cannot convert undefined or null to object');
		}

		target = Object(target);
		for(var index = 1; index < arguments.length; index++) {
			var source = arguments[index];
			if(source != null) {
				for(var key in source) {
					if(Object.prototype.hasOwnProperty.call(source, key)) {
						target[key] = source[key];
					}
				}
			}
		}
		return target;
	};
}

/**
 * 获取url中"?"符后的字符串
 */
__utils.getUrlParam = function() {
	var url = location.search;
	var theRequest = new Object();
	if(url.indexOf("?") != -1) {
		var str = url.slice(1);
		strs = str.split("&");
		for(var i = 0; i < strs.length; i++) {
			theRequest[strs[i].split("=")[0]] = strs[i].split("=")[1];
		}
	}
	return theRequest;
}

/**
 * json数组去重(只比对基本数据类型))
 * @param {Array} arr json数组 e.g. [{key:1},{key:1},{key:2}]
 * @param {String} keys [key1,key2,...]
 * @param {Boolean} allowNull 是否允许值为空(如果keys是多字段，那么多字段同时为空才算空)也算重复，默认不允许
 */
__utils.uniqueJsonArray = function(arr, keys, allowNull) {
	if(!allowNull) {
		arr = arr.filter(function(item, index) {
			let count = 0
			for(let i = 0; i < keys.length; i++) {
				let key = keys[i]
				if(item[key] !== undefined && item[key] !== '' && item[key] !== null) {
					count++
					break
				}
			}
			return count > 0
		})
	}
	if(arr && keys) {
		let temp = []
		for(let i = 0; i < arr.length; i++) {
			let item = arr[i]
			let isPush = false
			for(let j = 0; j < temp.length; j++) {

				let count = 0
				for(let k = 0; k < keys.length; k++) {
					let key = keys[k]
					if(temp[j][key] == item[key]) count++
				}

				if(count == keys.length) {
					isPush = true
					break
				}
			}
			if(!isPush) {
				temp.push(item)
			}
		}
		return temp
	}
	return arr
}

/**
 * 十六进制颜色随机
 * @param {Number} type 2:rgba; 1:rgb; 0:#xxxxxx;
 * @param {Number} opcity
 */
__utils.randomColor = function(type, opcity) {
	var r = Math.floor(Math.random() * 256);
	var g = Math.floor(Math.random() * 256);
	var b = Math.floor(Math.random() * 256);
	if(type == 1) {
		return 'rgb(' + r + ',' + g + ',' + b + ')';
	} else if(type == 2) {
		return 'rgba(' + r + ',' + g + ',' + b + ',' + (opcity || 1) + ')';
	} else {
		let newR = r.toString(16),
			newG = g.toString(16),
			newB = r.toString(16);
		return '#' + (newR.length < 2 ? '0' + newR : newR) + (newG.length < 2 ? '0' + newG : newG) + (newB.length < 2 ? '0' + newB : newB);
	}
}

//RGB(A)颜色转换为HEX十六进制的颜色值
__utils.rgbToHex = function(val) {
	var r,
		g,
		b,
		a,
		//判断rgb颜色值格式的正则表达式，如rgba(255,20,10,.54)
		regRgba = /rgba?\((\d{1,3}),(\d{1,3}),(\d{1,3})(,([.\d]+))?\)/,
		rsa = val.replace(/\s+/g, '').match(regRgba);
	if(!!rsa) {
		r = parseInt(rsa[1]).toString(16);
		r = r.length == 1 ? '0' + r : r;
		g = (+rsa[2]).toString(16);
		g = g.length == 1 ? '0' + g : g;
		b = (+rsa[3]).toString(16);
		b = b.length == 1 ? '0' + b : b;
		a = +(rsa[5] ? rsa[5] : 1) * 100;
		return {
			hex: '#' + r + g + b,
			alpha: Math.ceil(a)
		};
	} else {
		return {
			hex: val,
			alpha: 100
		};
	}
}

//HEX十六进制颜色值转换为RGB(A)颜色值
__utils.hexToRgb = function(val, alpha) {
	var a, b, c;
	if(/^#/g.test(val)) {

		// 如果只有三位的值，需变成六位，如：#fff => #ffffff
		if(val.length === 4) {
			var colorNew = "#";
			for(var i = 1; i < 4; i += 1) {
				colorNew += val.slice(i, i + 1).concat(val.slice(i, i + 1));
			}
			val = colorNew;
		}

		a = val.slice(1, 3);
		b = val.slice(3, 5);
		c = val.slice(5, 7);
		if(alpha == undefined && alpha == null) {
			return(
				'rgb(' +
				parseInt(a, 16) +
				',' +
				parseInt(b, 16) +
				',' +
				parseInt(c, 16) +
				')'
			);
		}
		return(
			'rgba(' +
			parseInt(a, 16) +
			',' +
			parseInt(b, 16) +
			',' +
			parseInt(c, 16) +
			',' +
			alpha +
			')'
		);
	} else {
		return {
			rgba: '无效值：' + val
		};
	}
}

__utils.isNotEmpty = function(str){
	if(str === '' || str === null || str === undefined){
		return false
	}
	return true
}

/**
 * 设置表格占满高度
 * @param {Number} offsetBottom 表格底部距离
*/
__utils.resizeFullTable = function(offsetBottom){
	offsetBottom = offsetBottom || 0
	let element = document.getElementsByClassName('el-table__header')
	if(element.length){
		let top = element[0].getBoundingClientRect().top
		let winHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
		// 32：页面组件高度；45：表格头部高度；
		return winHeight - top - 32 - 45 - offsetBottom
	}
	return 'auto'

}

/**
 * 添加秒
 * @param {[type]} num [整数]
 */
 Date.prototype.addSeconds = function(num) {
	this.setSeconds(this.getSeconds() + num);
	return this;
};
/**
 * 添加分钟
 * @param {Number} num [整数]
 */
Date.prototype.addMinutes = function(num) {
	this.setMinutes(this.getMinutes() + num);
	return this;
};
/**
 * 添加小时
 * @param {Number} num [整数]
 */
Date.prototype.addHours = function(num) {
	this.setHours(this.getHours() + num);
	return this;
};
/**
 * 添加天数
 * @param {Number} num [整数]
 */
Date.prototype.addDays = function(num) {
	this.setDate(this.getDate() + num);
	return this;
};
/**
 * 添加周
 * @param {Number} num [整数]
 */
Date.prototype.addWeeks = function(num) {
	this.setDate(this.addDays(num * 7).getDate());
	return this;
};
/**
 * 添加月
 * @param {Number} num [整数]
 */
Date.prototype.addMonths = function(num) {
	var d = this.getDate();
	this.setMonth(this.getMonth() + num);
	if(this.getDate() < d)
		this.setDate(0);
	return this;
};
/**
 * 添加年
 * @param {Number} num [整数]
 */
Date.prototype.addYears = function(num) {
	this.setFullYear(this.getFullYear() + num);
	return this;
};
/**
 * 获取周
 * @param {Number} num [整数] 下周或上周，以此类推
 * @param {Number} type [整数] 0：周一到周日；1：周日到周六
 */
Date.prototype.getWeek = function(num, type) {
	num = num || 0;
	var week = num * 7;
	var year = this.getFullYear();
	var month = this.getMonth();
	var day = this.getDate();
	var dayOfWeek = this.getDay();
	return type ? [
		// 0->周日,则上半周有1天，下半周6天
		new Date(year, month, day - dayOfWeek + week, 0, 0, 0).toLocaleString(),
		new Date(year, month, day + 6 - dayOfWeek + week, 23, 59, 59).toLocaleString()
	] : [
		// dayOfWeek + 6 是为了把 dayOfWeek = 0 的时候，映射成6 0->周日,则上半周有6天，下半周一天. 计算公式来自  0 == dayOfWeek ? (day - 6): (day - dayOfWeek + 1)
		new Date(year, month, day - (dayOfWeek + 6) % 7 + week, 0, 0, 0).toLocaleString(),
		new Date(year, month, day + (7 - dayOfWeek) % 7 + week, 23, 59, 59).toLocaleString()
	]
}
/*
 * 获取今年某月第一天到最后一天， 不传月份默认是当前月
 * @param {Number} month [整数] 月份
 * @param {String} fmt 格式
 */
Date.prototype.getOneMonth = function(month, fmt) {
	var fmt = fmt || 'yyyy-MM-dd hh:mm:ss'
	var year = new Date().getFullYear()
	month = month !== undefined ? (month - 1) : new Date().getMonth()
	return {
		firstDay: new Date(year, month, 1).Format(fmt),
		lastDay: new Date(year, month + 1, 0).Format(fmt)
	}
}
/**
 * 格式化日期
 * @param {String} fmt 格式 e.g. yyyy-MM-dd hh:mm:ss.S
 */
Date.prototype.Format = function(fmt) {
	var o = {
		"M+": this.getMonth() + 1, // 月份
		"d+": this.getDate(), // 日
		"h+": this.getHours(), // 小时
		"m+": this.getMinutes(), // 分
		"s+": this.getSeconds(), // 秒
		"q+": Math.floor((this.getMonth() + 3) / 3), // 季度
		"S": this.getMilliseconds() // 毫秒
	};
	if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
	for(var k in o) {
		if(new RegExp("(" + k + ")").test(fmt)) {
			let temp = (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))
			fmt = fmt.replace(RegExp.$1, temp);
		}
	}
	return fmt;
}

export {
  __utils
}